package edu.zju.gis.dbfg.tileserver;

import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import static sun.nio.ch.IOStatus.EOF;

/**
 * @author Hu
 * @date 2019/9/5
 * 地图瓦片服务
 **/
@Controller
@RequestMapping("/tileservice")
public class TileServer {

  public static final String GEOJSON_MIME_TYPE = "application/json;type=geojson";

  /**
   * 根据x,y,z获取GeoJSON格式瓦片数据
   */
  @RequestMapping(value = "/{serviceId}/geojson/{z}/{x}/{y}", method = RequestMethod.GET)
  @ResponseBody
  public void getGeoJsonTile(@PathVariable("servideId")String serviceId, @PathVariable("z") Integer z,
                             @PathVariable("y") Integer y, @PathVariable("x") Integer x,
                             HttpServletResponse response) throws IOException {
    response.setContentType(GEOJSON_MIME_TYPE);
    ServletOutputStream outputStream = response.getOutputStream();
    String path = String.format("D:\\Work\\Study\\GeRenXueXi\\Code\\4_矢量瓦片\\data_宁波北仑_LCRA_polygon\\geojson\\%d\\%d_%d.geojson", z, x, y);
    File tile = new File(path);
    if (tile.exists()) {
      if (tile.canRead()){
        long filesize = tile.length();
        if(filesize > Integer.MAX_VALUE) {
          throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + filesize);
        }
        int size = (int)filesize;
        response.setContentLengthLong(size);
        FileInputStream fis = new FileInputStream(tile);
        byte[] bytes=new byte[size];
        // 读取文件所有的字节并返回
        int offset = 0;
        int readed;
        while (offset < size && (readed = fis.read(bytes, offset, size-offset)) != EOF) {
          offset += readed;
        }
        if (offset != size) {
          throw new IOException("Unexpected readed size. current: " + offset + ", excepted: " + size);
        }
        IOUtils.write(bytes, outputStream);
        outputStream.flush();
        outputStream.close();
      } else {
        byte[] msg = String.format("Geojson tile [%d, %d, %d] can not read", z, x, y).getBytes();
        IOUtils.write(msg, outputStream);
        response.setContentLength(msg.length);
        response.setStatus(500);
      }
    } else {
      byte[] msg = String.format("Geojson tile [%d, %d, %d] not exists", z, x, y).getBytes();
      IOUtils.write(msg, outputStream);
      response.setContentLength(msg.length);
      response.setStatus(404);
    }

  }


}
